package com.hadwinling.controller;

import com.hadwinling.entity.NuclearParam;
import com.hadwinling.service.RealTimeService;
import com.hadwinling.tool.Msg;
import org.apache.iotdb.rpc.IoTDBConnectionException;
import org.apache.iotdb.rpc.StatementExecutionException;
import org.apache.iotdb.session.SessionDataSet;
import org.apache.iotdb.tsfile.read.common.Field;
import org.apache.iotdb.tsfile.read.common.RowRecord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * @Classname RealTimeController
 * @Description TODO
 * @Date 2021/7/9 15:08
 * @Created by
 */
@Controller
@CrossOrigin() // 这个是设置跨域的
public class RealTimeController {
    @Autowired
    private RealTimeService realTimeService;

    @PostMapping("/realTimeInsertionWithSchedule")
    @ResponseBody
    public Msg realTimeInsertionWithSchedule(@RequestParam(value = "storage") String storage) {
        Msg msg = new Msg();
        long start = System.currentTimeMillis();
        realTimeService.realTimeInsertionWithSchedule(storage);
        long end = System.currentTimeMillis();
        msg.add("time", (end - start) / 1000.0);
        return msg;
    }


    /**
     * 1 .燃耗步 物理场 时间 4D
     *
     * @param nuclearParam 指标
     * @return 组件 和层
     */
    @PostMapping("/selectTheLastestTimeWithIndicatorReturnModule")
    @ResponseBody
    public Msg selectTheLastestTimeWithIndicatorReturnModule(@RequestBody NuclearParam nuclearParam) {
        Msg msg = new Msg();
        ArrayList<RowRecord> lists = null;
        try {
            lists = realTimeService.selectTheLastestTimeWithIndicatorReturnModule(nuclearParam);
        } catch (StatementExecutionException e) {
            e.printStackTrace();
            msg.setCode(100);
            msg.setMsg("出错啦");
            return msg;
        } catch (IoTDBConnectionException e) {
            e.printStackTrace();
            msg.setCode(100);
            msg.setMsg("出错啦");
            return msg;
        }
        if (lists == null) {
            msg.setCode(100);
            msg.setMsg("出错了");
            return msg;
        }

        msg.setMsg("成功啦");
        msg.setCode(200);

        Float min = Float.MAX_VALUE;
        Float max = Float.MIN_VALUE;

        Float[][] value = new Float[52][32];
        int row = 0;

        final long timestamp = lists.get(row).getTimestamp();
        msg.add("timestamp", timestamp);
        for (int i = 0; i < 52; i++) {
            for (int j = 0; j < 32; j++) {
                final RowRecord rowRecord = lists.get(row);
                final List<Field> fields = rowRecord.getFields();
                final Field field = fields.get(1);
                final String stringValue = field.getStringValue();
                final Float floatV = Float.valueOf(stringValue);
                value[i][j] = floatV;
                if (min > floatV) {
                    min = floatV;
                }
                if (max < floatV) {
                    max = floatV;
                }
                row++;
            }
        }
        msg.add("Max", max);
        msg.add("Min", min);

        int[] x = new int[8];
        int[] y = new int[8];
        for (int i = 0; i < 8; i++) {
            x[i] = i + 1;
            y[i] = i + 1;
        }
        msg.add("x", x);
        msg.add("y", y);

        // 层数
        int[] layers = new int[32];
        for (int t = 0; t < 32; t++) {
            layers[t] = (t + 1);
        }
        msg.add("layers", layers);

        msg.add("value", value);

        return msg;
    }

    /**
     * 查找最近第几个 数据
     *
     * @param nuclearParam
     * @return
     */
    @PostMapping("/selectTheLastestNoTimeWithIndicatorReturnModule")
    @ResponseBody
    public Msg selectTheLastestNoTimeWithIndicatorReturnModule(@RequestBody NuclearParam nuclearParam) {
        Msg msg = new Msg();
        ArrayList<RowRecord> rowRecords = null;
        try {
            rowRecords = realTimeService.selectTheLastestNoTimeWithIndicatorReturnModule(nuclearParam);
        } catch (StatementExecutionException e) {
            e.printStackTrace();
            msg.setCode(100);
            msg.setMsg("出错啦");
            return msg;
        } catch (IoTDBConnectionException e) {
            e.printStackTrace();
            msg.setCode(100);
            msg.setMsg("出错啦");
            return msg;
        }
        if (rowRecords == null) {
            msg.setCode(100);
            msg.setMsg("出错啦");
            return msg;
        }

        msg.setCode(200);
        msg.setMsg("成功啦");

        Float min = Float.MAX_VALUE;
        Float max = Float.MIN_VALUE;

        Float[][] value = new Float[52][32];
        int row = 0;
        final int rowRecords_size = rowRecords.size();
        System.out.println(rowRecords_size);
        final int time_end = nuclearParam.getTime_end();

        for (int i = time_end - 1; i < rowRecords_size; i = i + time_end) {
            final RowRecord rowRecord = rowRecords.get(i);
            final List<Field> fields = rowRecord.getFields();
            for (int j = 0; j < 32; j++) {
                final Field field = fields.get(j);
                final float floatV = field.getFloatV();
                value[row][j] = floatV;
                if (min > floatV) {
                    min = floatV;
                }
                if (max < floatV) {
                    max = floatV;
                }
            }
            row++;
        }
        msg.add("Max", max);
        msg.add("Min", min);

        int[] x = new int[8];
        int[] y = new int[8];
        for (int i = 0; i < 8; i++) {
            x[i] = i + 1;
            y[i] = i + 1;
        }
        msg.add("x", x);
        msg.add("y", y);

        // 层数
        int[] layers = new int[32];
        for (int t = 0; t < 32; t++) {
            layers[t] = (t + 1);
        }
        msg.add("layers", layers);

        msg.add("value", value);


        return msg;
    }

    /**
     * 2.燃耗步 物理场 时间
     *
     * @param nuclearParam 传入指标
     * @return 层 和 组件
     */
    @PostMapping("/selectTheLatestTimeWithReturnLayerAndModule")
    @ResponseBody
    public Msg selectTheLatestTimeWithReturnLayerAndModule(@RequestBody NuclearParam nuclearParam) {
        Msg msg = new Msg();
        ArrayList<List<Field>> lists = null;
        try {
            lists = realTimeService.selectTheLatestTimeWithReturnLayerAndModule(nuclearParam);
        } catch (StatementExecutionException e) {
            e.printStackTrace();
            msg.setCode(100);
            msg.setMsg("出错啦");
        } catch (IoTDBConnectionException e) {
            e.printStackTrace();
            msg.setCode(100);
            msg.setMsg("出错啦");
        }
        if (lists == null) {
            msg.setCode(100);
            msg.setMsg("出错了");
            return msg;
        }

        msg.setMsg("成功啦");
        msg.setCode(200);

        Float min = Float.MAX_VALUE;
        Float max = Float.MIN_VALUE;

        Float[][] value = new Float[52][32];
        int row = 0;
        for (int i = 0; i < 52; i++) {
            for (int j = 0; j < 32; j++) {
                final List<Field> fields = lists.get(row);
                final Field field = fields.get(1);
                final String stringValue = field.getStringValue();
                final Float floatV = Float.valueOf(stringValue);
                value[i][j] = floatV;
                if (min > floatV) {
                    min = floatV;
                }
                if (max < floatV) {
                    max = floatV;
                }
                row++;
            }
        }

        msg.add("Max", max);
        msg.add("Min", min);

        // 层数
        int[] layers = new int[32];
        for (int t = 0; t < 32; t++) {
            layers[t] = (t + 1);
        }
        msg.add("layers", layers);

        int[] module_nums = new int[52];
        for (int i = 0; i < 52; i++) {
            module_nums[i] = i + 1;
        }
        msg.add("module", module_nums);

        msg.add("value", value);
        return msg;
    }

    /**
     * 3 .燃耗步 物理场 组件
     *
     * @param nuclearParam 指标
     * @return 层 和 时刻
     */
    @PostMapping("/selectTheLatestTimeWithReturnLayerAndTime")
    @ResponseBody
    public Msg selectTheLatestTimeWithReturnLayerAndTime(@RequestBody NuclearParam nuclearParam) {
        Msg msg = new Msg();
        ArrayList<List<Field>> lists = null;
        try {
            lists = realTimeService.selectTheLatestTimeWithReturnLayerAndTime(nuclearParam);
        } catch (StatementExecutionException e) {
            e.printStackTrace();
            msg.setCode(100);
            msg.setMsg("出错了");
            return msg;
        } catch (IoTDBConnectionException e) {
            e.printStackTrace();
            msg.setCode(100);
            msg.setMsg("出错了");
            return msg;
        }
        if (lists == null) {
            msg.setCode(100);
            msg.setMsg("出错了");
            return msg;
        }
        msg.setMsg("成功啦");
        msg.setCode(200);

        Float min = Float.MAX_VALUE;
        Float max = Float.MIN_VALUE;
        Float[][] value = new Float[98][32];
        System.out.println("list size:" + lists.size());
        int row = 0;

        msg.add("Max", max);
        msg.add("Min", min);
        // 层数
        int[] layers = new int[32];
        for (int layer = 0; layer < 32; layer++) {
            layers[layer] = (layer + 1);
        }
        // 时刻数
        int[] times_num = new int[98];
        for (int t = 0; t < 98; t++) {
            times_num[t] = (t + 1);
        }
        msg.add("layers", layers);
        msg.add("time", times_num);

        msg.add("value", value);
        return msg;
    }

    /**
     * 4 时刻 组件 物理场 (bug)
     *
     * @param nuclearParam 物理场 组件
     * @return 层 和 燃耗步
     */
    @PostMapping("/selectTheLatestTimeWithReturnLayerAndBurn")
    @ResponseBody
    public Msg selectTheLatestTimeWithReturnLayerAndBurn(@RequestBody NuclearParam nuclearParam) {
        Msg msg = new Msg();
        ArrayList<List<Field>> lists = null;
        try {
            lists = realTimeService.selectTheLatestTimeWithReturnLayerAndBurn(nuclearParam);
        } catch (StatementExecutionException e) {
            e.printStackTrace();
            msg.setCode(100);
            msg.setMsg("出错了");
            return msg;
        } catch (IoTDBConnectionException e) {
            e.printStackTrace();
            msg.setCode(100);
            msg.setMsg("出错了");
            return msg;
        }
        if (lists == null) {
            msg.setCode(100);
            msg.setMsg("出错了");
            return msg;
        }

        msg.setMsg("成功啦");
        msg.setCode(200);

        Float min = Float.MAX_VALUE;
        Float max = Float.MIN_VALUE;
        Float[][] value = new Float[18][32];

        int row = 0;

        msg.add("Max", max);
        msg.add("Min", min);

        // 燃耗步数
        int[] burns = new int[18];
        for (int burn = 0; burn < 18; burn++) {
            burns[burn] = (burn + 1);
        }
        // 层数
        int[] layers = new int[32];
        for (int t = 0; t < 32; t++) {
            layers[t] = (t + 1);
        }
        msg.add("layers", layers);
        msg.add("burns", burns);

        msg.add("value", value);

        return msg;
    }


    /**
     * 2.1 plot_burn_ind_mod (burn,indicator,module)
     *
     * @param nuclearParam 传过来的值
     * @return
     */
    @PostMapping("/plot_burn_indicator_module_real_time")
    @ResponseBody
    public Msg plot_burn_indicator_module_real_time(@RequestBody NuclearParam nuclearParam) {
        Msg msg = new Msg();
        ArrayList<List<Field>> lists = null;
        try {
            lists = realTimeService.plot_burn_indicator_module_real_time(nuclearParam);
        } catch (StatementExecutionException e) {
            e.printStackTrace();
            msg.setCode(100);
            msg.setMsg("出错了");
            return msg;
        } catch (IoTDBConnectionException e) {
            e.printStackTrace();
            msg.setCode(100);
            msg.setMsg("出错了");
            return msg;
        }
        if (lists == null) {
            msg.setCode(100);
            msg.setMsg("出错了");
            return msg;
        }

        msg.add("value", lists);

        return msg;
    }

}
